package com.gxc.recursion;

/**
 * 题目：给定一个数组arr，代表数值不同的纸牌排成一条线。
 * 玩家A和玩家B依次拿走每张纸牌，规定玩家A先拿，玩家B后拿，
 * 但是每个玩家每次只能拿走最左或最右的纸牌，玩家A和玩家B都绝顶聪明。请返回最后获胜者的分数。
 * 【举例】
 * arr=[1,2,100,4]。
 * 开始时，玩家A只能拿走1或4。如果开始时玩家A拿走1，则排列变为[2,100,4]，
 * 接下来玩家B可以拿走2或4，然后继续轮到玩家A...
 * 如果开始时玩家A拿走4，则排列变为[1,2,100]，接下来玩家B可以拿走1或100，然后继续轮到玩家A...
 * 玩家A作为绝顶聪明的人不会先拿4，因为拿4之后，玩家B将拿走100。
 * 所以玩家A会先拿1，让排列变为[2,100,4]，接下来玩家B不管怎么选，100都会被玩家A拿走。玩家A会获胜，分数为101。
 * 所以返回101。
 * arr=[1,100,2]。开始时，玩家A不管拿1还是2，玩家B作为绝顶聪明的人，都会把100拿走。
 * 玩家B会获胜，分数为100。所以返回100。
 */
public class CardInLine {

    public static void main(String[] args) {
        int[] arr = new int[]{1,2,100,4};
        int[] arr2 = new int[]{1,100,2};
        System.out.println(win1(arr));
        System.out.println(win1(arr2));
    }

    private static int win1(int[] arr) {
        if (arr == null || arr.length ==0) return 0;

        return Math.max(first(arr, 0, arr.length-1), after(arr, 0, arr.length-1));
    }

    /**
     *
     * @param arr
     * @param l 左边
     * @param r 右边
     * @return
     */
    private static int first(int[] arr, int l, int r) {
        //如果只剩一张牌，且是先手，则拿最后的牌
        if (l == r) return arr[l];
        //先手如果拿的左边的牌，则后手只能拿[l+1,r]
        //先手如果拿的右边的牌，则后手只能拿[l,r-1]
        //先手为了让自己最大，取两种情况的最大值
        return Math.max(arr[l]+after(arr, l+1, r), arr[r]+after(arr, l, r-1));
    }

    /**
     *
     * @param arr
     * @param l 左边
     * @param r 右边
     * @return
     */
    private static int after(int[] arr, int l, int r) {
        //如果只剩一张牌，且是后手，则没牌拿
        if (l == r) return 0;
        //后手如果拿的左边的牌，则先手只能拿[l+1,r]
        //后手如果拿的右边的牌，则先手只能拿[l,r-1]
        //后手要最大，则先手拿走的都是小牌，则后手最大
        return Math.min(first(arr, l+1, r), first(arr, l, r-1));
    }



}
